package com.example.cscot;

import org.json.JSONArray;

//
// 掌握几个JAVA几个特点，就能理解和C++的不一样
// （其实现代C++也都支持啦，只是平时写算法时不用）
// 1、没有指针概念，所有对象其实都是类似C++的指针概念
// 2、可以函数任意处定义函数（匿名函数）
// 3、可以函数任意处定义类
// 关键是理解RtCallback抽象类如何定义，是调用函数时定义其实现（要背下来）

//
// 适配不同的大模型完成对话，理论上应该用Java继承机制来做
// 我们这里实现不用继承方法，但可以好好体会继承的好处
public class LewayChat {
    //
    // 区别不同的AI大模型
    public String mMagicName;
    //
    // 添加各种大模型支持
    public XfSpark mXfChat;
    public DbArk mDbChat;
    //
    // 通过这个来使用大模型，屏蔽不同大模型API的区别
    public LewayChat(String magicName) {
        mMagicName = magicName;
        if (mMagicName.equals("XF_Spark")) {
            mXfChat = new XfSpark();
        }
        if (mMagicName.equals("DB_Ark")) {
            mDbChat = new DbArk();
        }
        mSessionDone = false;
    }
    //
    // 初始化
    // strInit是考虑将来可能的扩展，目前看来没有必要
    public int initChat(String strInit) {
        if (mMagicName.equals("XF_Spark")) {
            return mXfChat.initXfSpark("");
        }
        if (mMagicName.equals("DB_Ark")) {
            return mDbChat.initArk("");
        }
        return -1;
    }
    //
    // 初始化
    public int uninitChat() {
        if (mMagicName.equals("XF_Spark")) {
            return mXfChat.uninitXfSpark();
        }
        if (mMagicName.equals("DB_Ark")) {
            return mDbChat.uninitArk();
        }
        return -1;
    }
    //
    // 专门用来设置全局印象的设置的，也就是智能体背景设定的，设定后就一直起作用的。
    // 就是假定你是谁。。。的设置
    // 可以在多次异步通话间起作用，但是整体超5000字就失效啦
    // 可以多次调用，切换或者确定自己的角色，其实是通过和服务器在后台进行内部通话来实现的
    public void prepareRole(String whatRole, RtCallback cb) {
        if (mMagicName.equals("XF_Spark")) {
            mXfChat.prepareRole(whatRole, cb);
        }
        if (mMagicName.equals("DB_Ark")) {
            mDbChat.prepareRole(whatRole, cb);
        }
    }
    //
    // 提交聊天历史，最后一条应该是你要问AI的，最终答案会通过回调函数通知你的
    // pastChats：   是以往的交流结果，可以为空array，可以包含你的RAG甚至prepareRole的设置信息
    // userRequest： 是这次你要问AI的，可以很简单，也可以很复杂，包含很多RAG信息或者设置信息
    // cb：          完成后会通过这个回调通知你AI的答案全部回来啦
    public void postChats(JSONArray pastChats, String userRequest, RtCallback cb) {
        if (mMagicName.equals("XF_Spark")) {
            mXfChat.postSDK(pastChats, userRequest, cb, true);
        }
        if (mMagicName.equals("DB_Ark")) {
            mDbChat.postChats(pastChats, userRequest, cb);
        }
    }
    //
    // 这个是配合cb调用确认是不是AI返回了所有答案，你问AI一次，AI可能会调用cb很多次，你需要哪次
    // 是最后一次。之后上次和cb的session结束啦，你才能开始下一次和AI的聊天
    // TBD：当前实现没有考虑如果中间断了怎么办，这是加强程序如何处理异常的事情啦
    public boolean mSessionDone;
}
